Though complex software is frequently written to handle many operating conditions, it is difficult to develop complex software that completely accounts for all possible conditions. Accordingly, software may encounter operating states that it is not expressly programmed to address. When condition that the software has not been programmed to address are encountered at run time, the software may “crash” the computer on which it is executing or other errors may occur. To deal with errors that occur at run-time while one or more processors executes computer software, exception handlers were developed. Exception handlers allow software a chance to correct problems and/or halt the execution of the software program in a manner that minimizes lost data or other disruptions. It is also possible to capture diagnostic information regarding the error and send this data to the developer of the software, upon approval by the user executing the software, so that the software may be improved or bugs can be fixed.
Accordingly, an operating system or other platform on which software may execute may have an exception handling system. When an error condition is encountered during the execution of some block of code, the exception handling system may halt execution of that block of code and then attempt to identify an error handler appropriate to use for that block of code.
Software is generally written such that a first main function calls one or more other functions. These functions themselves may call one or more additional functions. This is repeated chain of function calls representing a hierarchy of functions executing on one or more processors is referred to as a “call stack”. Traditionally, this call stack was executed by a single unit of execution, known as a “thread.” If an exception was thrown by a function buried deep in a call stack, and that function was not associated with an exception handler that could handle the exception, then the exception was passed from function to function, up the call stack, until the exception could be handled. Propagation information regarding the path the exception took through the call stack was bundled with other information about the exception. This propagation information represented an exception history that was useful to the developer of the software when trying to correct bugs in the software.
Modern computer systems often execute software on multiple, parallel threads that may be running on multiple processors. Therefore a single user task may be spread across many threads on many processors. Using traditional exception handling in this environment typically results in missing or incorrect exception propagation information.